//
// * Copyright (c) 2002-2009 "Neo Technology,"
// *     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// * This file is part of Neo4j.
// * 
// * Neo4j is free software: you can redistribute it and/or modify
// * it under the terms of the GNU Affero General Public License as
// * published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version.
// * 
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU Affero General Public License for more details.
// * 
// * You should have received a copy of the GNU Affero General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.kernel.impl.core
{

	using Node = org.neo4j.graphdb.Node;
	using EmbeddedGraphDatabase = org.neo4j.kernel.EmbeddedGraphDatabase;
	using AbstractNeo4jTestCase = org.neo4j.kernel.impl.AbstractNeo4jTestCase;
	using NeoModule = org.neo4j.kernel.impl.core.NeoModule;

	public class TestPropertyTypes : AbstractNeo4jTestCase
	{
		private Node node1 = null;

		public TestPropertyTypes(string testName) : base(testName)
		{
		}

		public override void setUp()
		{
			base.setUp();
			node1 = getGraphDb().createNode();
		}

		public override void tearDown()
		{
			node1.delete();
			getTransaction().success();
			base.tearDown();
		}

		private void clearCache()
		{
			NeoModule neoModule = ((EmbeddedGraphDatabase) getGraphDb()).getConfig().getNeoModule();
			neoModule.getNodeManager().clearCache();
		}

		public virtual void testDoubleType()
		{
			double dValue = new double(45.678d);
			string key = "testdouble";
			node1.setProperty(key, dValue);
			newTransaction();
			clearCache();
			double propertyValue = null;
			propertyValue = (double) node1.getProperty(key);
			assertEquals(dValue, propertyValue);
			dValue = new double(56784.3243d);
			node1.setProperty(key, dValue);
			newTransaction();
			clearCache();
			propertyValue = (double) node1.getProperty(key);
			assertEquals(dValue, propertyValue);

			node1.removeProperty(key);
			newTransaction();
			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testFloatType()
		{
			float fValue = new float(45.678f);
			string key = "testfloat";
			node1.setProperty(key, fValue);
			newTransaction();

			clearCache();
			float propertyValue = null;
			propertyValue = (float) node1.getProperty(key);
			assertEquals(fValue, propertyValue);

			fValue = new float(5684.3243f);
			node1.setProperty(key, fValue);
			newTransaction();

			clearCache();
			propertyValue = (float) node1.getProperty(key);
			assertEquals(fValue, propertyValue);

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testLongType()
		{
			long time = System.currentTimeMillis();
			long lValue = new long(time);
			string key = "testlong";
			node1.setProperty(key, lValue);
			newTransaction();

			clearCache();
			long propertyValue = null;
			propertyValue = (long) node1.getProperty(key);
			assertEquals(lValue, propertyValue);

			lValue = new long(System.currentTimeMillis());
			node1.setProperty(key, lValue);
			newTransaction();

			clearCache();
			propertyValue = (long) node1.getProperty(key);
			assertEquals(lValue, propertyValue);

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testByteType()
		{
			sbyte b = (sbyte) 177;
			sbyte bValue = new sbyte(b);
			string key = "testbyte";
			node1.setProperty(key, bValue);
			newTransaction();

			clearCache();
			sbyte propertyValue = null;
			propertyValue = (sbyte) node1.getProperty(key);
			assertEquals(bValue, propertyValue);

			bValue = new sbyte((sbyte) 200);
			node1.setProperty(key, bValue);
			newTransaction();

			clearCache();
			propertyValue = (sbyte) node1.getProperty(key);
			assertEquals(bValue, propertyValue);

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testShortType()
		{
			short @value = 453;
			short sValue = new short(@value);
			string key = "testshort";
			node1.setProperty(key, sValue);
			newTransaction();

			clearCache();
			short propertyValue = null;
			propertyValue = (short) node1.getProperty(key);
			assertEquals(sValue, propertyValue);

			sValue = new short((short) 5335);
			node1.setProperty(key, sValue);
			newTransaction();

			clearCache();
			propertyValue = (short) node1.getProperty(key);
			assertEquals(sValue, propertyValue);

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testCharType()
		{
			char c = 'c';
			char cValue = new char(c);
			string key = "testchar";
			node1.setProperty(key, cValue);
			newTransaction();

			clearCache();
			char propertyValue = null;
			propertyValue = (char) node1.getProperty(key);
			assertEquals(cValue, propertyValue);

			cValue = new char('d');
			node1.setProperty(key, cValue);
			newTransaction();

			clearCache();
			propertyValue = (char) node1.getProperty(key);
			assertEquals(cValue, propertyValue);

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testIntArray()
		{
			int[] array1 = new int[] { 1, 2, 3, 4, 5 };
			int[] array2 = new int[] { 6, 7, 8 };
			string key = "testintarray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			int[] propertyValue = null;
			propertyValue = (int[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (int[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new int(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testShortArray()
		{
			short[] array1 = new short[] { 1, 2, 3, 4, 5 };
			short[] array2 = new short[] { 6, 7, 8 };
			string key = "testintarray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			short[] propertyValue = null;
			propertyValue = (short[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (short[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new short(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testStringArray()
		{
			string[] array1 = new string[] { "a", "b", "c", "d", "e" };
			string[] array2 = new string[] { "ff", "gg", "hh" };
			string key = "teststringarray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			string[] propertyValue = null;
			propertyValue = (string[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (string[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], propertyValue[i]);
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testBooleanArray()
		{
			bool[] array1 = new bool[] { true, false, true, false, true };
			bool[] array2 = new bool[] { false, true, false };
			string key = "testboolarray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			bool[] propertyValue = null;
			propertyValue = (bool[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (bool[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new bool(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testDoubleArray()
		{
			double[] array1 = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0 };
			double[] array2 = new double[] { 6.0, 7.0, 8.0 };
			string key = "testdoublearray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			double[] propertyValue = null;
			propertyValue = (double[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (double[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new double(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testFloatArray()
		{
			float[] array1 = new float[] { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
			float[] array2 = new float[] { 6.0f, 7.0f, 8.0f };
			string key = "testfloatarray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			float[] propertyValue = null;
			propertyValue = (float[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (float[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new float(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testLongArray()
		{
			long[] array1 = new long[] { 1, 2, 3, 4, 5 };
			long[] array2 = new long[] { 6l, 7l, 8l };
			string key = "testlongarray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			long[] propertyValue = null;
			propertyValue = (long[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (long[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new long(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testByteArray()
		{
			sbyte[] array1 = new sbyte[] { 1, 2, 3, 4, 5 };
			sbyte[] array2 = new sbyte[] { 6, 7, 8 };
			string key = "testbytearray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			sbyte[] propertyValue = null;
			propertyValue = (sbyte[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (sbyte[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new sbyte(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}

		public virtual void testCharArray()
		{
			char[] array1 = new char[] { '1', '2', '3', '4', '5' };
			char[] array2 = new char[] { '6', '7', '8' };
			string key = "testchararray";
			node1.setProperty(key, array1);
			newTransaction();

			clearCache();
			char[] propertyValue = null;
			propertyValue = (char[]) node1.getProperty(key);
			assertEquals(array1.Length, propertyValue.Length);
			for (int i = 0; i < array1.Length; i++)
			{
				assertEquals(array1[i], propertyValue[i]);
			}

			node1.setProperty(key, array2);
			newTransaction();

			clearCache();
			propertyValue = (char[]) node1.getProperty(key);
			assertEquals(array2.Length, propertyValue.Length);
			for (int i = 0; i < array2.Length; i++)
			{
				assertEquals(array2[i], new char(propertyValue[i]));
			}

			node1.removeProperty(key);
			newTransaction();

			clearCache();
			assertTrue(!node1.hasProperty(key));
		}
	}
}